﻿#include "pch.h"
#include "MainPageViewModel.h"
#include "MainPageViewModel.g.cpp"
#include <filesystem>
#include "Utils.h"

namespace winrt::NovelReader::implementation
{
	MainPageViewModel::MainPageViewModel()
	{
		m_bookChapters = winrt::single_threaded_observable_vector<winrt::NovelReader::Chapter>(); 

		m_contentsVisibility = winrt::Microsoft::UI::Xaml::Visibility::Visible; 
		m_userSettings = winrt::NovelReader::AppService::UserSettings(); 
		m_userSettings.PropertyChanged({this, &MainPageViewModel::OnSettingsChanged});

		this->LoadChapters(false); 
	}

	winrt::Microsoft::UI::Xaml::Visibility MainPageViewModel::ContentsVisibility() const
	{
		return m_contentsVisibility; 
	}

	void MainPageViewModel::SetContentsVisibility(winrt::Microsoft::UI::Xaml::Visibility value)
	{
		if (value != m_contentsVisibility) {
			m_contentsVisibility = value; 
			this->RaisePropertyChanged(L"ContentsVisibility");
		}
	}

	winrt::Windows::Foundation::Collections::IVector<winrt::NovelReader::Chapter> MainPageViewModel::BookChapters()
	{
		return m_bookChapters; 
	}

	void MainPageViewModel::BookChapters(winrt::Windows::Foundation::Collections::IVector<winrt::NovelReader::Chapter> const& value)
	{
		if (value != m_bookChapters) {
			m_bookChapters = value; 
			this->RaisePropertyChanged(L"BookChapters"); 
		}
	}

	winrt::hstring MainPageViewModel::DisplayText() const
	{
		return m_displayText; 
	}

	void MainPageViewModel::DisplayText(winrt::hstring const& value)
	{
		if (value != m_displayText) {
			m_displayText = value; 
			this->RaisePropertyChanged(L"DisplayText"); 
		}
	}

	winrt::event_token MainPageViewModel::DisplayTitleChanged(winrt::NovelReader::StringActionHandler const& handler)
	{
		return m_displayTitleChanged.add(handler); 
	}

	void MainPageViewModel::DisplayTitleChanged(winrt::event_token const& token) noexcept
	{
		m_displayTitleChanged.remove(token); 
	}

	winrt::NovelReader::Chapter MainPageViewModel::SelectedChapter()
	{
		return m_selectedChapter; 
	}

	void MainPageViewModel::SelectedChapter(winrt::NovelReader::Chapter const& value)
	{
		if (m_selectedChapter != value)
		{
			m_selectedChapter = value; 
			this->RaisePropertyChanged(L"SelectedChapter"); 

			if (value == nullptr) {
				return;
			}
			
			m_userSettings.ChapterIndex(value.Index()); 
			this->UpdateDisplayTitle(value.Title()); 
			this->RaisePropertyChanged(L"DisplayText"); 
		}
	}

	double MainPageViewModel::FontSize() const
	{
		return m_userSettings.FontSize(); 
	}

	winrt::Microsoft::UI::Xaml::Media::FontFamily MainPageViewModel::FontFamily() const
	{
		return Service::LookupAppResource<winrt::Microsoft::UI::Xaml::Media::FontFamily>(m_userSettings.FontName()); 
	}

	winrt::Microsoft::UI::Xaml::Style MainPageViewModel::ThemeStyle() const
	{
		winrt::hstring themeKey;
		auto themeIndex = m_userSettings.ThemeIndex();

		if (themeIndex == -1) {
			themeKey = winrt::NovelReader::Service::IsDarkMode() ? L"Theme_Dark" : L"Theme_White";
		}
		else {
			themeKey = L"Theme_" + winrt::to_hstring(themeIndex);
		}
		return Service::LookupAppResource<winrt::Microsoft::UI::Xaml::Style>(themeKey); 
	}

	bool MainPageViewModel::IsLoading()
	{
		return m_isLoading; 
	}

	void MainPageViewModel::IsLoading(bool value)
	{
		if (m_isLoading != value) {
			m_isLoading = value; 
			this->RaisePropertyChanged(L"IsLoading"); 
		}
	}

	void MainPageViewModel::UpdateDisplayTitle(winrt::hstring const& chapterTitle)
	{
		if (!chapterTitle.empty()) {
			m_chapterTitle = chapterTitle;
			this->m_displayTitleChanged(m_bookName + L" - " + m_chapterTitle); 
		}
	}

	winrt::fire_and_forget MainPageViewModel::LoadChapters(bool isNewFile)
	{

		auto filePath = winrt::NovelReader::AppService::UserSettings().FilePath();
		if (!std::filesystem::exists(filePath.c_str())) {
			co_return; 
		}
		this->IsLoading(true);

		auto manager = winrt::NovelReader::ChapterManager(filePath); 
		m_bookName = manager.BookName();
		
		winrt::NovelReader::ChapterCollection collection = co_await manager.GetChaptersAsync(); 
		this->BookChapters().Clear(); 
		for (auto chapter : collection.ChaptersArray()) {
			this->BookChapters().Append(chapter); 
		}

		this->IsLoading(false);

		if (collection.ChaptersArray().empty()) {
			co_return; 
		}
	

		if (isNewFile) {
			this->SelectedChapter(collection.GetAt(0)); 
		}
		else {
			this->SelectedChapter(collection.GetAt(m_userSettings.ChapterIndex())); 
		}
	}

	void MainPageViewModel::OnSettingsChanged(
		winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Data::PropertyChangedEventArgs const& args)
	{
		auto propertyName = args.PropertyName(); 
		if (propertyName == L"FilePath") {
			this->LoadChapters(true);
		}
		else if (propertyName == L"WhiteLines") {
			if (m_selectedChapter != nullptr) {
				this->RaisePropertyChanged(L"DisplayText"); 
			}
		}
		else if (propertyName == L"FontSize") {
			this->RaisePropertyChanged(L"FontSize"); 
		}
		else if (propertyName == L"FontName") {
			this->RaisePropertyChanged(L"FontFamily"); 
		}
		else if (propertyName == L"ThemeIndex") {
			this->RaisePropertyChanged(L"ThemeStyle"); 
		}

		// test api 
		/*std::vector<winrt::hstring> strs; 
		winrt::array_view<winrt::hstring> array {strs}; */
	}
}
